use std::fs;

use serde::Deserialize;

use crate::components;
use crate::runtime::error::MagicBoxError;
use crate::runtime::response::{Code, MagicBoxResponse};
use crate::runtime::result::MagicBoxResult;
use crate::utils::request;

const GEOSITE_URL: &'static str = "https://api.github.com/repos/v2fly/domain-list-community/releases/latest";
const DATA_FILE_URL: &'static str = "https://github.com/v2fly/domain-list-community/releases/download/{TAG_NAME}/dlc.dat";

#[derive(Debug, Default, Clone, Deserialize)]
struct GithubRelease {
    tag_name: String,
}

#[tauri::command(rename_all = "snake_case")]
pub(crate) async fn invoke_component_v2ray_update_geosite() -> MagicBoxResult<MagicBoxResponse<()>> {
    let release = request::github_get_data::<GithubRelease>(GEOSITE_URL).await?;
    let content = request::github_get_bytes(DATA_FILE_URL.replace("{TAG_NAME}", release.tag_name.as_str()).as_str()).await?;

    let geosite_path = components::v2ray::manager::manager().install_path()?;
    let result = fs::write(geosite_path.join("geosite.dat"), content);
    if result.is_err() {
        let err = result.unwrap_err().to_string();
        log::error!("写入数据文件失败: {}", err.as_str());

        return Err(MagicBoxError::new(Code::IoError, format!("写入数据文件失败: {}", err.as_str()).as_str()));
    }

    Ok(MagicBoxResponse::new_empty_success())
}